package org.statewalker.fsm;

import java.util.ArrayList;
import java.util.List;

public class FsmCompositeProcessListener<S, E>
    implements
    IFsmProcessListener<S, E> {

    private List<IFsmProcessListener<S, E>> fListeners = new ArrayList<IFsmProcessListener<S, E>>();

    public synchronized void addListener(IFsmProcessListener<S, E> listener) {
        ArrayList<IFsmProcessListener<S, E>> listeners = new ArrayList<IFsmProcessListener<S, E>>(
            fListeners);
        listeners.add(listener);
        fListeners = listeners;
    }

    /**
     * @see org.statewalker.fsm.IFsmProcessListener#beginState(org.statewalker.fsm.FsmProcess,
     *      java.lang.Object)
     */
    public void beginState(FsmProcess<S, E> process, S state) {
        List<IFsmProcessListener<S, E>> listeners = fListeners;
        for (IFsmProcessListener<S, E> listener : listeners) {
            listener.beginState(process, state);
        }
    }

    /**
     * @see org.statewalker.fsm.IFsmProcessListener#endState(org.statewalker.fsm.FsmProcess,
     *      java.lang.Object)
     */
    public void endState(FsmProcess<S, E> process, S state) {
        List<IFsmProcessListener<S, E>> listeners = fListeners;
        for (IFsmProcessListener<S, E> listener : listeners) {
            listener.endState(process, state);
        }
    }

    /**
     * @see org.statewalker.fsm.IFsmProcessListener#onTransition(org.statewalker.fsm.FsmProcess,
     *      java.lang.Object, java.lang.Object, java.lang.Object)
     */
    public void onTransition(FsmProcess<S, E> process, S prev, E event, S next) {
        List<IFsmProcessListener<S, E>> listeners = fListeners;
        for (IFsmProcessListener<S, E> listener : listeners) {
            listener.onTransition(process, prev, event, next);
        }
    }

    public synchronized void removeListener(IFsmProcessListener<S, E> listener) {
        ArrayList<IFsmProcessListener<S, E>> listeners = new ArrayList<IFsmProcessListener<S, E>>(
            fListeners);
        listeners.remove(listener);
        fListeners = listeners;
    }

}
